"use strict";
this.AJAXForms = function () {};

this.AJAXForms.prototype = (function () {
    var init, thread, forms, areas, onConfigurationLoaded, onRedraw, initForm,
            hasFileInputs, initNonFileForm, createNewIframe, document,
            iframeContainer;

    document = this.document;

    init = function (webLayout) {
        areas = [];
        forms = [];
        iframeContainer = document.createElement('span');
        iframeContainer.style.display = 'none';
        webLayout.contentElement.appendChild(iframeContainer);
    };

    thread = function () {};

    onConfigurationLoaded = function (webLayout, config) {
        var i, targetElement, j, forms, previousState, area, target, url;
        if (config[this.NAME] === undefined) {
            return;
        }
        areas = config[this.NAME];
        for (i = areas.length - 1; i >= 0; i -= 1) {
            targetElement = webLayout.xPath(areas[i].target)[0];
            forms = webLayout.xPath(areas[i].forms);
            for (j = forms.length - 1; j >= 0; j -= 1) {
                initForm(forms[j], targetElement, areas[i], i, webLayout);
            }
        }
        if (!webLayout.getModule('HashStorage')) {
            return;
        }
        previousState = webLayout.getModule('HashStorage').load('AJAXForms');
        if (previousState !== undefined) {
            area = config[previousState.area];
            if (area) {
                target = webLayout.xPath(area.target)[0];
                url = previousState.url.replace(new RegExp(area.match),
                        area.replace);
                webLayout.ajaxLib.load(url, previousState.data, target,
                        function () {
                    webLayout.redraw(target);
                });
            }
        }
    };

    onRedraw = function (webLayout, details) {
        var i, j, k, newForms, targetElement, newForm;
        for (i = areas.length - 1; i >= 0; i -= 1) {
            targetElement = webLayout.xPath(areas[i].target)[0];
            newForms = webLayout.xPath(areas[i].forms);
            for (j = newForms.length - 1; j >= 0; j -= 1) {
                newForm = true;
                for (k = forms.length - 1; k >= 0; k -= 1) {
                    if (forms[k] === newForms[j]) {
                        newForm = false;
                    }
                }
                if (newForm) {
                    initForm(newForms[j], targetElement, areas[i], i,
                            webLayout);
                }
            }
        }
    };

    initForm = function (form, targetElement, area, areaIndex, webLayout) {
        var iframe, iframeInitialized;
        if (hasFileInputs(form)) {
            if (area.noFiles) {
                return;
            }
            iframe = createNewIframe(webLayout);
            form.target = iframe.name;
            form.action = form.action.replace(new RegExp(area.match),
                    area.replace);
            iframeInitialized = false;
            webLayout.addEventListener(form, 'submit', function () {
                if (iframeInitialized) {
                    return;
                }
                webLayout.addEventListener(iframe, 'load', function () {
                    if (iframe.contentWindow !== undefined) {
                        targetElement.innerHTML =
                                iframe.contentWindow.document.body.innerHTML;
                    } else {
                        targetElement.innerHTML =
                                this.contentDocument.body.innerHTML;
                    }
                    webLayout.redraw(targetElement);
                });
            });
        } else {
            initNonFileForm(form, targetElement, area, areaIndex, webLayout);
        }
        forms.push(form);
    };

    createNewIframe = function (webLayout) {
        var iframe, id;
        iframe = document.createElement('span');
        id = Math.random();
        while (document.getElementsByName('AJAXForms' + id).length > 0) {
            id += 1;
        }
        iframe.innerHTML = '<iframe name="AJAXForms' + id + '"></iframe>';
        iframeContainer.appendChild(iframe);
        return iframe.firstChild;
    };

    initNonFileForm = function (form, targetElement, area, areaIndex, webLayout) {
        webLayout.addEventListener(form, 'submit', function (e) {
            webLayout.preventDefault(e);
            var link, data;
            link = form.action.replace(new RegExp(area.match),
                    area.replace);
            data = webLayout.ajaxLib.serialize(form);
            if (form.method.toLowerCase() === 'post') {
                webLayout.ajaxLib.load(link, data, targetElement,
                        function () {
                    var storage;
                    storage = webLayout.getModule('HashStorage');
                    if (storage) {
                        storage.save('AJAXForms');
                        storage.save('AJAXLinks');
                    }
                    webLayout.redraw(targetElement);
                });
            } else {
                webLayout.ajaxLib.load(link + (link.indexOf('?') > -1 ?
                        '&' : '?') + webLayout.ajaxLib.encodeObject(data),
                        '', targetElement, function () {
                    var storage;
                    storage = webLayout.getModule('HashStorage');
                    if (storage) {
                        storage.save('AJAXForms', {
                            area: areaIndex,
                            url: form.action,
                            data: data
                        });
                        storage.save('AJAXLinks');
                    }
                    webLayout.redraw(targetElement);
                });
            }
        });
    };

    hasFileInputs = function (form) {
        var inputs, i;
        inputs = form.getElementsByTagName('input');
        for (i = inputs.length - 1; i >= 0; i -= 1) {
            if (inputs[i].type.toLowerCase() === 'file') {
                return true;
            }
        }
        return false;
    };

    return {
        NAME: 'AJAXForms',
        init: init,
        thread: thread,
        onConfigurationLoaded: onConfigurationLoaded,
        onRedraw: onRedraw
    };
}());